// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html

import GameEvent from "../../Commons/GameEvent";
import AudioManager, { AudioEffectType } from "../../Managers/AudioManager";
import SaveManager from "../../Managers/SaveManager";
import UIManager from "../../Managers/UIManager";
import TaskManager from "../Tasks/TaskManager";
import AttributeTemplate from "./AttributeTemplate";
import EquipEntity from "./EquipEntity";
import EquipTemplate from "./EquipTemplate";

export enum EquipEvent {
    ADDNEWEQUIP_EVENT = "addNewEquip_event",
    WEAREQUIP_EVENT = "wearEquip_event",
    TAKEOFFEQUIP_EVENT = "takeoffEquip_event",
    RECYCLEEQUIP_EVENT = "recycleEquip_Event"
}

export enum EquipPart {
    weapon,
    helmet,
    armor,
    foot,
    hand
}

export default class EquipManager implements IModelManager {
    private static _single: EquipManager = null;
    private equipMap: Map<number, EquipTemplate>;
    private attributeMap: Map<number, AttributeTemplate>;
    public static get single(): EquipManager {
        if (EquipManager._single == null) {
            EquipManager._single = new EquipManager();
        }
        return EquipManager._single;
    }

    initConfig(): void {
        this.equipMap = new Map();
        var jsonAss = cc.resources.get("configs/equip", cc.JsonAsset);
        for (const iterator of jsonAss.json) {
            var tp = new EquipTemplate();
            tp.init(iterator);
            this.equipMap.set(tp.id, tp);
        }

        this.attributeMap = new Map();
        jsonAss = cc.resources.get("configs/attribute", cc.JsonAsset);
        for (const iterator of jsonAss.json) {
            var attributeTp = new AttributeTemplate();
            attributeTp.init(iterator);
            this.attributeMap.set(attributeTp.id, attributeTp);
        }
    }

    getEquipTemplate(id: number): EquipTemplate {
        return this.equipMap.get(id);
    }

    getAttributeTemplate(id: number): AttributeTemplate {
        return this.attributeMap.get(id);
    }
    getEquipTemplateArr(): EquipTemplate[] {
        var arr = [];
        this.equipMap.forEach((value: EquipTemplate, key: number, map: Map<number, EquipTemplate>) => {
            arr.push(value);
        }, this);
        return arr;
    }

    getEquipEntity(id: number): EquipEntity {
        return SaveManager.single.userdata.getEquipEntity(id);
    }
    getEquipBagList(): EquipEntity[] {
        var userdata = SaveManager.single.userdata;
        return userdata.equipBagList;
    }
    getEquipAttribute(attId: number): number {
        var equipWearList = SaveManager.single.userdata.equipWearList;
        var sum: number = 0;
        for (const iterator of equipWearList) {
            var ey = this.getEquipEntity(iterator);
            if (ey != null && ey.equipTp.attributeId0 == attId) {
                sum += ey.attributeValue;
            }
        }
        return sum;
    }

    isWear(id: number): boolean {
        var equipTp = this.getEquipTemplate(id);
        if (equipTp == null) {
            return false;
        }
        var userdata = SaveManager.single.userdata;
        for (const equipId of userdata.equipWearList) {
            if (equipId <= 0) {
                continue;
            }
            var tp = this.getEquipTemplate(equipId);
            if (tp != null && tp.equipPart == equipTp.equipPart) {
                return true;
            }
        }

        return false;

    }

    requestAddEquip(id: number) {
        var ey = this.getEquipEntity(id);
        if (ey != null) {
            ey.getExp(ey.expValue);
        } else {
            var userdata = SaveManager.single.userdata;
            userdata.equipBagList.push(new EquipEntity({ id: id, level: 1, isWear: false }));
            ey = this.getEquipEntity(id);
            UIManager.single.showTips("获得装备<@>。".replace("@", ey.equipTp.equipName));
        }
        SaveManager.single.saveData();
        GameEvent.eventNode.emit(EquipEvent.ADDNEWEQUIP_EVENT);

        TaskManager.single.requestUpdataTaskPregress(105, 1);
    }
    public findIdleEquipIndx(): number {
        var userdata = SaveManager.single.userdata;
        for (let i = 0; i < userdata.equipWearList.length; i++) {
            if (userdata.equipWearList[i] == 0) {

                return i;
            }
        }
        return -1;
    }
    requestWearEquip(id: number) {
        var ey = this.getEquipEntity(id);
        if (!ey) {
            return;
        }
        let idleIndex = this.findIdleEquipIndx();
        if (idleIndex == -1) {
            UIManager.single.showTips("可装备格子已满。");
            return;
        }
        if (this.isWear(id)) {
            UIManager.single.showTips("这个部位已穿戴装备。");
            return;
        }

        ey.isWear = true;
        var userdata = SaveManager.single.userdata;
        for (let i = 0; i < userdata.equipWearList.length; i++) {
            if (userdata.equipWearList[i] == 0) {
                userdata.equipWearList[i] = id;
                break;
            }
        }

        SaveManager.single.saveData();
        GameEvent.eventNode.emit(EquipEvent.WEAREQUIP_EVENT);
        UIManager.single.showTips("穿戴成功。");
    }

    requestTakeoffEquip(id: number) {
        var ey = this.getEquipEntity(id);
        if (!ey) {
            return;
        }
        ey.isWear = false;
        var userdata = SaveManager.single.userdata;
        for (let i = 0; i < userdata.equipWearList.length; i++) {
            if (userdata.equipWearList[i] == id) {
                userdata.equipWearList[i] = 0;
                break;
            }
        }
        SaveManager.single.saveData();
        GameEvent.eventNode.emit(EquipEvent.TAKEOFFEQUIP_EVENT);
        UIManager.single.showTips("卸下成功。");
    }

    requestRecycleEquip(id: number) {
        var ey = this.getEquipEntity(id);
        if (!ey) {
            return;
        }
        if (ey.isWear) {
            UIManager.single.showTips("穿戴的装备无法回收。");
            return;
        }
        var userdata = SaveManager.single.userdata;
        var index = userdata.equipBagList.indexOf(ey);
        if (index != -1) {
            userdata.equipBagList.splice(index, 1);
            var addGoleNum = 500 * ey.level + 100 * ey.equipTp.quality;
            if (userdata.perpetualCard != null) {
                addGoleNum *= 2;
            } else if (userdata.monthCard != null && !userdata.monthCard.isOutDate) {
                addGoleNum *= 1.5;
            }
            userdata.gold += Math.ceil(addGoleNum);
            AudioManager.single.playEffect(AudioEffectType.goldDrop);
            SaveManager.single.saveData();
            UIManager.single.showTips("回收成功，金币+" + Math.ceil(addGoleNum) + "。");
            GameEvent.eventNode.emit(EquipEvent.RECYCLEEQUIP_EVENT);
            GameEvent.eventNode.emit(GameEvent.CURRENCYUPDATA_EVENT);
        }

    }
}
